package 集合;

import org.junit.Test;

import java.util.*;
/**
 * Java集合可分为Collection和Map两种体系
 * Collection接口：单列数据，定义了存取一组【对象】的方法的集合
 *      List：有序，可重复集合------->“动态”数组
 *          1.ArrayList(List接口的主要实现类,线程不安全,效率高,底层用Object[] elementData存储,
 *                      在JDK7底层创建了初始长度为10的数组,若存入的数据数量大于数组长度,则默认>>1相当于扩容1.5倍,还小时扩容为元素个数长度,最大取至整型最大值
 *                      在JDK8底层创建了初始长度为{}的数组,第一次调用add()时才赋予数组长度,延迟了数组的创建,节省了内存)
 *          2.LinkedList (在频繁使用插入、删除操作时效率高于,线程不安全，ArrayList,底层用双向链表存储
 *                        内部声明了Node类的first和last属性,默认值为null,调用add()时创建了Node对象)
 *          3.Vector(JDK1.0最初的List集合,线程安全,效率低,底层用Object[] elementData存储,默认扩容2倍)
 *      Set：无序，不可重复------>数组+链表
 *          1.HashSet(Set接口的主要实现类,线程不安全,可储存null值
 *                    底层创建了初始长度为16的数组,本质上底层是HashMap,
 *                    将Map中的value设置为静态常量new Object即为Set)
 *          2.LinkedHashSet(HashSet的子类,被遍历时可按照添加的顺序
 *                          在HashSet基础上添加了双向链表来记录存储顺序
 *                           频繁遍历时效率更高)
 *          3.TreeSet(可以按照添加的对象指定属性,进行排序,底层是二叉树
 *                    排序对象需重写compareTo,属性不同抛出ClassCastException异常)
 * Map接口：双列数据，保存具有“key-value”类【数据】的集合----->类似函数
 *          1.HashMap(重点、好用：线程不安全,无序,效率高,可以存放null,key不能重复【存放数据时equals()对比key的hashCode值】
 *                    在JDK7底层创建了初始长度为16的数组Entry[] table,若存入的数据数量大于临界值时,则默认扩容2倍，底层结构为数组+链表
 *                    在JDK8底层创建了初始长度为{}的数组Node[],第一次调用put()时才赋予长度为16的数组,底层结构为数组+链表+红黑树
 *                    当数组某一位置上的元素以链表形式存在的元素个数>8且数组长度>64时,此位置上的所有元素改为用红黑树储存
 *                    注：(threshold)扩容的临界值=容量*填充/负载/加载、因子/系数(loadFactor=0.75),最大容量2^30)
 *          2.LinkedHashMap(HashMap的子类(数组Node[])继承了,在原有HashMap基础上添加了一对指针(before和after),指向前后元素
 *                          遍历元素时按照添加的顺序遍历,频繁遍历时效率更高)
 *          3.TreeMap(按添加的key-value对进行排序,此时考虑key的自然排序或定制排序
 *                    底层使用红黑树)
 *          4.Hashtable(最初的Map实现类,线程安全,效率低,不能存放null)
 *          5.Properties(Hashtable的子类,常用来处理配置文件,key和value都是String类型)
 * 注意事项  1.contains(Object obj):在判断当前集合中是否包含obj时会调用obj对象所在类的equals()
 */
public class collectionDemo {
    @Test
    public void test(){
        Collection<Object> al = new ArrayList<>(20);//带参构造器,提前设置集合长度,避免后台多次扩容
        //1.集合加入元素
        al.add("AA");
        al.add(123);
        //2.返回集合大小
        al.size();
        //3.返回是否为空
        al.isEmpty();
        //4.清空集合
        al.clear();
        //5.返回是否包含元素
        al.contains("123");
        //6.用工具类Arrays的aslist方法建立匿名集合，判断两个集合是否包含关系
        al.containsAll(Arrays.asList("aaa"));
        //7.移除元素，成功返回true
        al.remove(123);
        //8.保留两个集合的交际
        al.retainAll(Arrays.asList(123));
        System.out.println(al.remove(123));
        al.add(123);
        al.add("444");
        //9.返回对象的哈希值
        System.out.println(al.hashCode());
        //10.集合--->数组
        Object[] objects = al.toArray();
        for (Object o:objects)
            System.out.println(o);
        //11.数组--->集合(注意：基本数据类型在Arrays.asList()里是一个对象，须写包装类)
        List<String> strings = Arrays.asList(new String[]{"a", "bb", "ccc"});
        List i = Arrays.asList(new int[]{123, 456, 789});
        List ii = Arrays.asList(new Integer[]{123, 456, 789});
        System.out.println(strings);
        System.out.println(i.size());//1
        System.out.println(ii.size());//3
        //12.iterator():返回Iterator迭代器接口的实例，用于遍历元素(此时不能进行元素的增删否则会出现线程安全问题)
        Iterator<Object> iterator = al.iterator();
        if(iterator.hasNext())
            //【指针】下移，存在下一个hasNext()返回true，next()返回对象
            System.out.println(iterator.next());
        iterator.remove();//移除迭代器指针和当前元素
    }
}
